package com.gitee.wsl.model

import com.gitee.wsl.api.Closeable
import com.gitee.wsl.eventbus.Events
import com.gitee.wsl.model.plugin.PLUGIN_INSTALLED_LIST
import com.gitee.wsl.prop.AttributeKey
import com.gitee.wsl.prop.Attributes
import com.gitee.wsl.prop.AttributesContainer
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CompletableJob
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlin.coroutines.CoroutineContext


abstract class Model<T:Model<T>> (
    val applicationJob: CompletableJob,
    //open val config:ModelConfig<T>,
    override val attributes: Attributes = Attributes()
):AttributesContainer, CoroutineScope, Closeable {

    val monitor: Events = Events()

    private val closed = atomic(false)

    private val clientJob: CompletableJob = Job(applicationJob)

    override val coroutineContext: CoroutineContext =  clientJob

    val config:ModelConfig<T> = ModelConfig<T>()

    /**
     * Closes the underlying [engine].
     */
    override fun close() {
        val success = closed.compareAndSet(expect = false, update = true)
        if (!success) return

        val installedFeatures = attributes[PLUGIN_INSTALLED_LIST]
        installedFeatures.allKeys.forEach { key ->
            @Suppress("UNCHECKED_CAST")
            val plugin = installedFeatures[key as AttributeKey<Any>]

            if (plugin is Closeable) {
                plugin.close()
            }
        }

        clientJob.complete()
        /*if (manageEngine) {
            engine.close()
        }*/
    }

    /**
     * Returns a new [HttpClient] by copying this client's configuration
     * and additionally configured by the [block] parameter.
     */
     //abstract fun config(block: ModelConfig<T>.() -> Unit): T

}
